<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-10-31
 * Time: 22:06
 */

namespace app\common\model\traits;

use app\common\enum\OrderEnum;
use app\common\enum\OrderType;
use app\common\exception\OrderException;
use app\common\exception\ParameterException;
use app\common\model\MpApiUserToken;
use app\common\validate\Order as Validate;
use app\common\service\WxPay as WxPayService;
use think\facade\Log;

trait HandleUserOrder
{
    /**
     * 创建订单
     * @param $params
     * @return array
     */
    public static function createOrder($params)
    {
        $validate = new Validate();
        if (!$validate->scene('create')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        $user_id = MpApiUserToken::getCurrentUID();
        $openid = MpApiUserToken::getCurrentTokenVar('openid');

        $resultOptions = (new WxPayService())->createOrder(
            $params['body'],
            $params['total_fee'],
            $openid,
            $params['notify_url'],
            isset($params['attach']) ? $params['attach'] : '');

        // 区分订单类型
        switch ($params['type']) {
            case OrderType::Appreciate:
                self::addOrder([
                    'title' => isset($params['title']) ? $params['title'] : '图鸟科技',
                    'img_url' => isset($params['img_url']) ? $params['img_url'] : '',
                    'user_id' => $user_id,
                    'order_no' => $resultOptions['order_no'],
                    'prepay_id' => $resultOptions['prepay_id'],
                    'amount' => $params['total_fee'],
                    'allow_pay_subscribe' => $params['allow_pay_subscribe'],
                    'allow_refund_subscribe' => $params['allow_refund_subscribe'],
                    'allow_submit_success_subscribe' => $params['allow_submit_success_subscribe'],
                    'allow_pay_timeout_subscribe' => $params['allow_pay_timeout_subscribe'],
                    'type' => $params['type'],
                ]);
                break;
        }

        return $resultOptions;
    }

    /**
     * 用户主动取消订单支付
     * @param $order_no
     */
    public static function cancelOrder($order_no)
    {
        $validate = new Validate();
        if (!$validate->scene('cancel')->check(['order_no' => $order_no])) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        self::updateByOrderNo($order_no, ['status', 'order_end_time'], [
            'status' => OrderEnum::PAY_ERROR,
            'order_end_time' => time()
        ]);
    }

    /**
     * 验证和发起订单退款
     * @param $params
     * @return bool
     */
    public static function refundOrder($params)
    {
        $validate = new Validate();
        if (!$validate->scene('refund')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        // 根据id查找到订单的原来数据
        $static = static::find($params['id']);

//        Log::record(json_encode($params, JSON_UNESCAPED_UNICODE), 'error');
//        Log::record(json_encode($static->toArray(), JSON_UNESCAPED_UNICODE), 'error');

        if ($static->amount == 0 || ($static->status != OrderEnum::PAY_SUCCESS && $static->status != OrderEnum::USER_CREATE_REFUND)) {
            throw new OrderException([
                'code' => 403,
                'errorCode' => 50002,
                'msg' => '发起退款配置参数错误',
            ]);
        }

        $result = (new WxPayService())->refundOrder(
            $static->transaction_id,
            $static->amount,
            $params['refund_amount'],
            $params['notify_url'],
            $params['refund_desc']);

        // 更新订单信息，将退款单号和订单状态写入数据库
        $result = $static->allowField(['out_order_no','refund_amount','refund_desc','refund_create_time','status'])
            ->save([
                'out_order_no' => $result['out_refund_no'],
                'refund_amount' => $params['refund_amount'],
                'refund_desc' => $params['refund_desc'],
                'refund_create_time' => time(),
                'status' => OrderEnum::CREATE_REFUND,
            ]);

        if ($result !== false) {
            return true;
        } else {
            return false;
        }
    }
}